package com.meida.common.mybatis.base.service.impl;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jayway.jsonpath.Criteria;
import com.meida.common.constants.CommonConstants;
import com.meida.common.constants.QueueConstants;
import com.meida.common.lock.RedissonLocker;
import com.meida.common.mybatis.base.mapper.SuperMapper;
import com.meida.common.mybatis.base.service.IBaseService;
import com.meida.common.mybatis.entity.EntityMap;
import com.meida.common.mybatis.interceptor.*;
import com.meida.common.mybatis.model.*;
import com.meida.common.mybatis.query.CriteriaDelete;
import com.meida.common.mybatis.query.CriteriaQuery;
import com.meida.common.mybatis.query.CriteriaSave;
import com.meida.common.mybatis.query.CriteriaUpdate;
import com.meida.common.utils.*;
import io.swagger.annotations.Api;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.ibatis.annotations.Param;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.cloud.bus.BusProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @author: zyf
 * @date: 2018/12/24 12:49
 * @desc: 父类service
 */
public abstract class BaseServiceImpl<M extends SuperMapper<T>, T> extends ServiceImpl<M, T> implements IBaseService<T> {

    @Autowired
    public ApplicationContext applicationContext;
    @Autowired
    public RedisUtils redisUtils;
    @Resource
    public AutowireCapableBeanFactory spring;

    @Autowired
    public RedissonLocker redisLock;

    @Resource
    public SqlSessionTemplate sqlSession;

    /**
     *
     */
    @Autowired
    public ApplicationEventPublisher publisher;

    @Autowired
    public BusProperties busProperties;

    @Autowired
    public AmqpTemplate amqpTemplate;

    public Class<T> entityClass = null;

    /**
     * 事务管理器
     */
    @Autowired
    private PlatformTransactionManager platformTransactionManager;

    /**
     * 事务的一些基础信息如超时时间、隔离级别、传播属性等
     */
    @Autowired
    private TransactionDefinition transactionDefinition;


    public void pushEvent(ApplicationEvent applicationEvent) {
        applicationContext.publishEvent(applicationEvent);
    }

    public BaseServiceImpl() {
        Type t = getClass().getGenericSuperclass();
        if (t instanceof ParameterizedType) {
            Type[] p = ((ParameterizedType) t).getActualTypeArguments();
            entityClass = (Class<T>) p[1];
        }
    }

    /**
     * 自定分页方法,可通过自定义处理器扩展
     */
    public ResultBody basePageList(CriteriaQuery<?> cq) {
        ResultBody resultBody = new ResultBody();
        EntityMap extra = resultBody.getExtra();
        Boolean hanHandler = false;
        //扩展事件
        PageInterceptor pageInterceptor = SpringContextHolder.getHandler(cq.getHandlerName(), PageInterceptor.class);
        if (ObjectUtils.isNotEmpty(pageInterceptor)) {
            hanHandler = true;
            //执行校验
            resultBody = pageInterceptor.validate(cq, cq.getRequestMap());
        }
        if (resultBody.isOk()) {
            if (hanHandler) {
                pageInterceptor.prepare(cq, cq.getPageParams(), cq.getRequestMap());
            }
            PageParams pageParams = cq.getPageParams();
            IPage<EntityMap> result = this.baseMapper.pageList(new Page(pageParams.getCurrent(), pageParams.getSize()), cq);
            EntityMap.setEnumConvertInterceptor(null);
            if (ObjectUtils.isNotNull(result)) {
                //扩展查询结果集
                if (hanHandler) {
                    pageInterceptor.complete(cq, result.getRecords(), extra);
                    pageInterceptor.complete(cq, result, extra);
                }
            }
            if (pageParams.getSimpleData().equals(CommonConstants.INT_1)) {
                resultBody = resultBody.data(result).setExtra(extra);
            } else {
                EntityMap data = new EntityMap();
                data.put("records", result.getRecords());
                if (FlymeUtils.isNotEmpty(extra)) {
                    data.put("extra", extra);
                }
                resultBody = resultBody.data(data);
            }
        }
        return resultBody;
    }

    /**
     * selectEntityMap方法带扩展事件
     */
    public ResultBody baseGet(CriteriaQuery<?> cq) {
        EntityMap result = new EntityMap();
        boolean hasHandler = false;
        ResultBody resultBody = new ResultBody();
        //获取扩展事件名称
        GetInterceptor getInterceptor = SpringContextHolder.getHandler(cq.getHandlerName(), GetInterceptor.class);
        //扩展查询条件
        if (FlymeUtils.isNotEmpty(getInterceptor)) {
            hasHandler = true;
            resultBody = getInterceptor.validate(cq, cq.getRequestMap());
        }
        if (resultBody.isOk()) {
            if (hasHandler) {
                getInterceptor.prepare(cq, cq.getRequestMap());
            }
            String condition = cq.getCustomSqlSegment();
            if (FlymeUtils.isEmpty(condition)) {
                ApiAssert.failure("查询条件不存在");
            }
            List<EntityMap> maps = baseMapper.selectEntityMap(cq);
            if (ObjectUtils.isNotNull(maps)) {
                result = maps.get(0);
                //扩展查询结果集
                if (hasHandler) {
                    getInterceptor.complete(cq, result);
                }
            }
        }
        return resultBody.data(result);
    }


    /**
     * 查询单个实体
     *
     * @param cq
     * @return
     */
    @Override
    public EntityMap findOne(CriteriaQuery cq) {
        EntityMap result = new EntityMap();
        List<EntityMap> maps = selectEntityMap(cq);
        if (ObjectUtils.isNotNull(maps)) {
            if (maps.size() > 1) {
                ApiAssert.failure("数据异常");
            } else {
                return maps.get(0);
            }
        }
        return result;
    }

    /**
     * 根据单个属性查询
     *
     * @param propertyName
     * @param value
     * @return
     */
    @Override
    public T getByProperty(String propertyName, Object value) {
        CriteriaQuery cq = new CriteriaQuery(entityClass);
        cq.eq(true, propertyName, value);
        return (T) getOne(cq);
    }

    /**
     * 查询单个实体
     *
     * @param id
     * @return
     */
    @Override
    public EntityMap findOne(Serializable id) {
        ApiAssert.isNotEmpty("ID不能为空", id);
        EntityMap result = new EntityMap();
        CriteriaQuery cq = new CriteriaQuery(entityClass);
        cq.eq(true, cq.getIdField(), id);
        return findOne(cq);
    }

    public ResultBody baseEdit(CriteriaUpdate cu) {
        T t = (T) cu.getEntity(entityClass);
        return baseEdit(cu, t);
    }

    /**
     * 自定义更新
     */
    public ResultBody baseEdit(CriteriaUpdate cu, T obj) {
        boolean isUpdate;
        //获取扩展事件
        UpdateInterceptor handler = SpringContextHolder.getHandler(cu.getHandlerName(), UpdateInterceptor.class);
        //更新前验证
        BaseMapper mapper = null;
        if (ObjectUtils.isNotNull(handler)) {
            ResultBody resultBody = handler.validate(cu, cu.getRequestMap());
            if (!resultBody.isOk()) {
                return resultBody;
            }
            handler.prepare(cu, cu.getRequestMap());
            //获取自定义mapper
            mapper = handler.getMapper();
        }
        if (FlymeUtils.isNotEmpty(mapper)) {
            obj = handler.getEntity(cu, cu.getRequestMap());
            isUpdate = handler.getMapper().update(obj, cu) > 0;
        } else {
            isUpdate = saveOrUpdate(obj, cu);
        }

        if (!isUpdate) {
            return ResultBody.failed("更新失败");
        }
        //更新成功后调用扩展事件
        if (FlymeUtils.isNotEmpty(handler)) {
            handler.complete(cu, cu.getRequestMap());
        }
        UpdateModel model = cu.getModel();

        Long[] fileIds = new Long[0];
        if (FlymeUtils.isNotEmpty(model)) {
            fileIds = model.getFileIds();
        } else {
            Object fileIdsStr = cu.getParams("fileIds");
            if (FlymeUtils.isNotEmpty(fileIdsStr)) {
                fileIds = FlymeUtils.StringArray2LongArray(FlymeUtils.getString(fileIdsStr.toString(), "").split(","));
            }
        }
        if (FlymeUtils.isNotEmpty(fileIds)) {
            saveFile(fileIds, obj, cu.getIdField(), cu.getCls().getSimpleName());
        }
        return ResultBody.ok("更新成功", obj);
    }

    /**
     * 自定义更新局部字段
     */
    public ResultBody baseUpdate(CriteriaUpdate cu) {
        boolean isUpdate;
        //获取扩展事件
        UpdateInterceptor handler = SpringContextHolder.getHandler(cu.getHandlerName(), UpdateInterceptor.class);
        //更新前验证
        if (ObjectUtils.isNotNull(handler)) {
            ResultBody resultBody = handler.validate(cu, cu.getRequestMap());
            if (!resultBody.isOk()) {
                return resultBody;
            }
            handler.prepare(cu, cu.getRequestMap());
        }
        isUpdate = update(cu);
        if (!isUpdate) {
            return ResultBody.failed("更新失败");
        }
        //更新成功后调用扩展事件
        if (FlymeUtils.isNotEmpty(handler)) {
            handler.complete(cu, cu.getRequestMap());
        }
        return ResultBody.ok("更新成功");
    }

    /**
     * 自定义删除
     *
     * @param cd
     * @return
     */
    public ResultBody baseDelete(CriteriaDelete cd) {
        //自定义扩展事件
        DeleteInterceptor handler = SpringContextHolder.getHandler(cd.getHandlerName(), DeleteInterceptor.class);
        if (FlymeUtils.isNotEmpty(handler)) {
            //执行校验
            ResultBody resultBody = handler.validate(cd, cd.getRequestMap());
            //验证失败直接返回
            if (!resultBody.isOk()) {
                return resultBody;
            }
            //执行条件预处理扩展
            handler.prepare(cd, cd.getRequestMap());
        }
        //检查是否有子节点
        checkHasChild(cd.getIdValue());
        //追加是否允许删除条件
        checkAllowDel(cd);
        ApiAssert.isNotEmpty("删除条件不存在", cd.getCustomSqlSegment());
        int n;
        if (cd.getLogicalDelete()) {
            n = baseMapper.delete(cd);
        } else {
            //强制删除
            n = baseMapper.deleteByCq(cd);
        }
        if (n <= 0) {
            return ResultBody.failed("删除失败");
        }
        if (FlymeUtils.isNotEmpty(handler)) {
            handler.complete(cd, cd.getRequestMap());
        }
        if (cd.getDelFile()) {
            DeleteModel deleteModel = cd.getModel();
            Long[] fileIds = new Long[0];
            if (FlymeUtils.isNotEmpty(deleteModel)) {
                fileIds = deleteModel.getIds();
            } else {
                fileIds = cd.getRequestMap().getLongs("fileIds");
            }
            delFiles(fileIds, cd.getCls().getSimpleName());
        }
        return ResultBody.ok("删除成功", n);

    }

    public ResultBody baseAdd(CriteriaSave cs) {
        return baseAdd(cs, cs.getEntity(entityClass));
    }


    /**
     * save方法带扩展事件
     */
    public ResultBody baseAdd(CriteriaSave cs, T obj) {
        SaveInterceptor handler = SpringContextHolder.getHandler(cs.getHandlerName(), SaveInterceptor.class);
        ResultBody resultBody = new ResultBody();
        //是否支持扩展条件
        boolean hasHandler = false;
        Boolean isSave = false;
        //获取自定义mapper
        BaseMapper mapper = null;
        if (ObjectUtils.isNotNull(handler)) {
            hasHandler = true;
            resultBody = handler.validate(cs, cs.getRequestMap());
            if (!resultBody.isOk()) {
                return resultBody;
            }
            handler.prepare(cs, cs.getRequestMap(), obj);
            mapper = handler.getMapper();
        }
        if (FlymeUtils.isNotEmpty(mapper)) {
            obj = (T) handler.getEntity(cs, cs.getRequestMap());
            isSave = handler.getMapper().insert(obj) > 0;
        } else {
            isSave = this.save(obj);
        }
        if (isSave) {
            resultBody = resultBody.ok("保存成功", obj);
            if (hasHandler) {
                //保存成功后调用扩展事件
                handler.complete(cs, cs.getRequestMap(), obj);
            }
            SaveModel saveModel = cs.getModel();
            Long[] fileIds = new Long[0];
            if (FlymeUtils.isNotEmpty(saveModel)) {
                fileIds = cs.getModel().getFileIds();
            } else {
                String fileIdsStr = cs.getParams("fileIds");
                if (FlymeUtils.isNotEmpty(fileIdsStr)) {
                    fileIds = FlymeUtils.StringArray2LongArray(fileIdsStr.split(","));
                }

            }
            if (FlymeUtils.isNotEmpty(fileIds)) {
                saveFile(fileIds, obj, cs.getIdField(), cs.getCls().getSimpleName());
            }
        }
        return resultBody.ok("保存成功", obj);

    }

    /**
     * List<EntityMap>
     *
     * @param cq
     * @return
     */
    @Override
    public List<EntityMap> selectEntityMap(CriteriaQuery<?> cq) {
        ApiAssert.isNotEmpty("服务器异常", cq.getCls());
        return baseMapper.selectEntityMap(cq);
    }

    /**
     * 根据条件构造器查询List<EntityMap>
     */
    public ResultBody baseList(CriteriaQuery<?> cq) {
        ResultBody resultBody = new ResultBody();
        EntityMap extra = resultBody.getExtra();
        Boolean hanHandler = false;
        //获取扩展事件名称
        ListInterceptor handler = SpringContextHolder.getHandler(cq.getHandlerName(), ListInterceptor.class);
        if (ObjectUtils.isNotEmpty(handler)) {
            hanHandler = true;
            //执行校验
            resultBody = handler.validate(cq, cq.getRequestMap());
        }
        if (resultBody.isOk()) {
            //扩展查询条件
            if (hanHandler) {
                handler.prepare(cq, cq.getListModel(), cq.getRequestMap());
            }
            List<EntityMap> result = baseMapper.selectEntityMap(cq);
            if (ObjectUtils.isNotNull(result)) {
                //扩展查询结果集
                if (hanHandler) {
                    handler.complete(cq, result, extra);
                }
            }
            resultBody = resultBody.data(result).setExtra(extra);
        }
        return resultBody;
    }

    /**
     * 自定义sql查询List<EntityMap>
     */
    public List<EntityMap> listEntityMap(String statement, EntityMap map) {
        if (ObjectUtils.isEmpty(map)) {
            return null;
        }
        return sqlSession.selectList(getMapperName() + statement, map);
    }

    /**
     * 自定义sql查询List<EntityMap>
     */
    public List<EntityMap> listEntityMap(String statement, @Param("ew") CriteriaQuery<?> cq) {
        return sqlSession.selectList(getMapperName() + statement, cq);
    }


    /**
     * 获取mapperName
     */
    private String getMapperName() {
        String mapperName = "";
        Class cl = baseMapper.getClass();
        Class<?> interfaces[] = cl.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            mapperName = anInterface.getName();
        }
        return mapperName + ".";
    }

    public List<T> selectAll() {
        return this.baseMapper.selectList(null);
    }


    @Override
    public ResultBody listEntityMap(ListModel listModel) {
        CriteriaQuery<EntityMap> cq = new CriteriaQuery(listModel, entityClass);
        cq.select(entityClass, "*");
        return baseList(cq);
    }


    /**
     * 自定义分页前扩展方法
     *
     * @param cq
     * @return
     */
    public ResultBody beforeListEntityMap(CriteriaQuery<T> cq, T t, EntityMap requestMap) {
        return ResultBody.ok();
    }


    /**
     * 自定义分页后扩展方法
     *
     * @param cq
     * @return
     */
    public ResultBody afterListEntityMap(CriteriaQuery<T> cq, List<EntityMap> data, ResultBody resultBody) {
        return resultBody;
    }


    @Override
    public ResultBody listEntityMap(Map map) {
        CriteriaQuery<T> cq = new CriteriaQuery(map, entityClass);
        ResultBody resultBody = beforeListEntityMap(cq, cq.getEntity(entityClass), cq.getRequestMap());
        if (resultBody.isOk()) {
            if (FlymeUtils.isEmpty(cq.getSetSelect())) {
                cq.select(entityClass, "*");
            }
            resultBody = baseList(cq);
            if (resultBody.isOk()) {
                List<EntityMap> data = (List<EntityMap>) resultBody.getData();
                resultBody = afterListEntityMap(cq, data, resultBody);
            }
        }
        return resultBody;
    }

    @Override
    @Deprecated
    public ResultBody pageList(PageModel pageModel) {
        CriteriaQuery<T> cq = new CriteriaQuery(pageModel, entityClass);
        cq.select(entityClass, "*");
        return basePageList(cq);
    }

    @Override
    public ResultBody pageList(Map map) {
        CriteriaQuery<T> cq = new CriteriaQuery(map, entityClass);
        ResultBody resultBody = beforePageList(cq, cq.getEntity(entityClass), cq.getRequestMap());
        if (resultBody.isOk()) {
            if (FlymeUtils.isEmpty(cq.getSetSelect())) {
                cq.select(entityClass, "*");
            }
            resultBody = basePageList(cq);
            if (resultBody.isOk()) {
                PageParams pageParams = cq.getPageParams();
                Object result = resultBody.getData();
                if (pageParams.getSimpleData().equals(CommonConstants.INT_1)) {
                    IPage<EntityMap> list = (IPage<EntityMap>) result;
                    afterPageList(cq, list.getRecords(), resultBody);
                } else {
                    EntityMap resultMap = (EntityMap) result;
                    List<EntityMap> records = resultMap.get("records");
                    afterPageList(cq, records, resultBody);
                }

                resultBody.data(result);
            }
        }

        return resultBody;
    }

    /**
     * 自定义分页前扩展方法
     *
     * @param cq
     * @return
     */
    public ResultBody beforePageList(CriteriaQuery<T> cq, T t, EntityMap requestMap) {
        return ResultBody.ok();
    }


    /**
     * 自定义分页后扩展方法
     *
     * @param cq
     * @return
     */
    public void afterPageList(CriteriaQuery<T> cq, List<EntityMap> data, ResultBody resultBody) {
    }


    /**
     * 自定义保存前扩展方法
     *
     * @param cq
     * @return
     */
    public ResultBody beforeAdd(CriteriaSave cs, T t, EntityMap extra) {
        return ResultBody.ok();

    }


    /**
     * 自定义保存后扩展方法
     *
     * @param cq
     * @return
     */
    public ResultBody afterAdd(CriteriaSave cs, T t, EntityMap extra) {

        return ResultBody.ok("保存成功", t);
    }


    @Override
    @Deprecated
    public ResultBody add(SaveModel model) {
        CriteriaSave cs = new CriteriaSave(model, entityClass);
        T obj = cs.getEntity(entityClass);
        ApiAssert.isNotEmpty("保存对象不能为空", obj);
        EntityMap extra = new EntityMap();
        ResultBody resultBody = beforeAdd(cs, obj, extra);
        if (resultBody.isOk()) {
            resultBody = baseAdd(cs, obj);
            if (resultBody.isOk()) {
                T t = (T) resultBody.getData();
                resultBody = afterAdd(cs, t, extra);
            }
        }
        return resultBody;
    }


    @Override
    public ResultBody add(Map map) {
        CriteriaSave cs = new CriteriaSave(map, entityClass);
        T obj = cs.getEntity(entityClass);
        EntityMap extra = new EntityMap();
        ApiAssert.isNotEmpty("保存对象不能为空", obj);
        ResultBody resultBody = beforeAdd(cs, obj, extra);
        if (resultBody.isOk()) {

            resultBody = baseAdd(cs, obj);
            if (resultBody.isOk()) {
                T t = (T) resultBody.getData();
                resultBody = afterAdd(cs, t, extra);
            }

        }
        return resultBody;
    }


    /**
     * 自定义更新前扩展方法
     *
     * @param cq
     * @return
     */
    public ResultBody beforeEdit(CriteriaUpdate<T> cu, T t) {
        return ResultBody.ok();
    }


    /**
     * 自定义更新后扩展方法
     *
     * @param cq
     * @return
     */
    public ResultBody afterEdit(CriteriaUpdate cu, T t) {
        return ResultBody.ok("更新成功", t);
    }


    @Override
    @Deprecated
    public ResultBody edit(UpdateModel model) {
        CriteriaUpdate cu = new CriteriaUpdate(model, entityClass);
        T obj = (T) cu.getEntity(entityClass);
        return baseEdit(cu, obj);
    }


    @Override
    public ResultBody edit(Map map) {
        CriteriaUpdate cu = new CriteriaUpdate(map, entityClass);
        T obj = (T) cu.getEntity(entityClass);
        ResultBody resultBody = beforeEdit(cu, obj);
        if (resultBody.isOk()) {

            resultBody = baseEdit(cu, obj);
            if (resultBody.isOk()) {
                T t = (T) resultBody.getData();
                resultBody = afterEdit(cu, t);
            }


        }
        return resultBody;
    }


    /**
     * 自定义删除前扩展方法
     *
     * @param cq
     * @return
     */
    public ResultBody beforeDelete(CriteriaDelete<T> cd) {
        return ResultBody.ok();
    }


    /**
     * 自定义删除后扩展方法
     *
     * @param cq
     * @return
     */
    public ResultBody afterDelete(CriteriaDelete cd, Long[] ids) {
        return ResultBody.msg("删除成功");
    }


    @Override
    public ResultBody delete(DeleteModel model) {
        CriteriaDelete cd = new CriteriaDelete(model, entityClass);
        return baseDelete(cd);
    }


    @Override
    public ResultBody delete(Map map) {
        CriteriaDelete cd = new CriteriaDelete(map, entityClass);
        ResultBody resultBody = beforeDelete(cd);
        if (resultBody.isOk()) {
            resultBody = baseDelete(cd);
            if (resultBody.isOk()) {
                resultBody = afterDelete(cd, cd.getIds());
            }
        }
        return resultBody;
    }


    /**
     * 自定义get扩展方法
     *
     * @param cq
     * @return
     */
    public ResultBody beforeGet(CriteriaQuery<T> cq, T t, EntityMap requestMap) {
        return ResultBody.ok();
    }


    /**
     * 自定义get扩展方法
     *
     * @param cq
     * @return
     */
    public void afterGet(CriteriaQuery cq, EntityMap result) {

    }

    @Override
    public ResultBody get(GetModel model) {
        CriteriaQuery<T> cq = new CriteriaQuery(model, entityClass);
        ResultBody resultBody = beforeGet(cq, cq.getEntity(entityClass), cq.getRequestMap());
        if (resultBody.isOk()) {

            resultBody = baseGet(cq);
            if (resultBody.isOk()) {
                EntityMap result = (EntityMap) resultBody.getData();
                afterGet(cq, result);
            }
        }
        return resultBody;
    }

    @Override
    public ResultBody get(Map map) {
        CriteriaQuery<T> cq = new CriteriaQuery(map, entityClass);
        ResultBody resultBody = beforeGet(cq, cq.getEntity(entityClass), cq.getRequestMap());
        if (resultBody.isOk()) {
            resultBody = baseGet(cq);
            if (resultBody.isOk()) {
                EntityMap result = (EntityMap) resultBody.getData();
                afterGet(cq, result);
                resultBody.data(result);
            }
        }
        return resultBody;
    }

    /**
     * 更新文件业务ID
     *
     * @param fileIds
     * @param obj
     * @param idField
     * @param entityEname
     */
    private void saveFile(Long[] fileIds, Object obj, String idField, String entityEname) {
        if (FlymeUtils.isNotEmpty(fileIds)) {
            Long busId = (Long) ReflectionUtils.getFieldValue(obj, idField);
            EntityMap map = new EntityMap();
            map.put("busId", busId);
            map.put("entityName", entityEname);
            map.put("fileIds", fileIds);
            //发布收藏点击事件
            amqpTemplate.convertAndSend(QueueConstants.QUEUE_UPLOADFILE, map);
        }
    }

    /**
     * 删除业务文件
     *
     * @param fileIds
     * @param obj
     * @param idField
     * @param entityEname
     */
    private void delFiles(Long[] busIds, String entityEname) {
        if (FlymeUtils.isNotEmpty(busIds)) {
            EntityMap map = new EntityMap();
            map.put("busIds", busIds);
            map.put("entityName", entityEname);
            //发布收藏点击事件
            amqpTemplate.convertAndSend(QueueConstants.QUEUE_DELFILE, map);
        }
    }

    /**
     * 自定义状态更新前扩展
     *
     * @param cq
     * @return
     */
    public ResultBody beforeSetState(CriteriaUpdate cq) {
        return ResultBody.ok();
    }


    /**
     * 自定义状态更新完成扩展
     *
     * @param cq
     * @return
     */
    public ResultBody afterSetState(CriteriaUpdate cq) {
        return ResultBody.ok();
    }

    /**
     * 根据主键通用状态更新方法
     *
     * @param model
     * @param state
     * @return
     */
    public ResultBody setState(Map map, String fieldName, Integer state) {
        CriteriaUpdate cq = new CriteriaUpdate(map, entityClass);
        ApiAssert.isNotEmpty("主键不能为空", cq.getIds());
        cq.set(fieldName, state);
        ResultBody resultBody = beforeSetState(cq);
        if (resultBody.isOk()) {
            ResultBody result = baseUpdate(cq);
            if (result.isOk()) {
                ResultBody after = afterSetState(cq);
                String text = redisUtils.getStateFieldLabel(fieldName, state.toString());
                if (FlymeUtils.isNotEmpty(after.getMessage())) {
                    return ResultBody.ok(after.getMessage(), state);
                } else {
                    return ResultBody.result(text, state);
                }

            }
        }
        return ResultBody.failed("操作失败");
    }

    /**
     * 查询数组
     *
     * @param cq
     * @return
     */
    public List<Long> selectLongs(CriteriaQuery cq) {
        return listObjs(cq, e -> new Long(e.toString()));
    }

    /**
     * 检查是否有子节点
     */
    private ResultBody checkHasChild(Long id) {
        String parentId = ReflectionUtils.getParentId(entityClass);
        if (FlymeUtils.isNotEmpty(parentId)) {
            CriteriaQuery cq = new CriteriaQuery(entityClass);
            int n = count(cq.eq("parentId", id));
            if (n > 0) {
                ApiAssert.failure("请先删除子节点");
            }
        }
        return ResultBody.ok();
    }

    /**
     * 检查是否允许删除
     */
    private ResultBody checkAllowDel(CriteriaDelete cd) {
        String allowDel = ReflectionUtils.getAllowDelField(entityClass);
        if (FlymeUtils.isNotEmpty(allowDel)) {
            cd.eq("allowDel", CommonConstants.ENABLED);
        }
        return ResultBody.ok();
    }



}
